/**
 * <p>该类表示一个页面控件, 可能是一个简单控件, 譬如标签、输入框， 也可能是一个复合控件，如表格等。 这些组件的通用功能是能够把自己渲染成一个DOM节点,
 * 这样能在浏览器中展示该控件. 控件一般都有唯一标识的ID, 在页面的上下文环境中可以根据ID获取该控件; 如果没有设ID, 系统不会在
 * 上下文环境中注册该控件.</p>
 * 
 * @class 页面控件接口类
 * @param {string} id 控件的ID
 */
zxt.ui.Widget = function(id) {
	zxt.core.Component.call(this, id);
	this._parent = null;
	this._focused = 0;
	this._mode = null;
	this._skeleton = null;
	this._validateStatus = {status:true,type:null,param:null,info:""};
};

zxt.defineClazz(zxt.ui.Widget, zxt.core.Component);

/**
 * <p>返回组件类型 - zxt.ui.Widget</p>
 * 
 * @function
 * @returns {string} 组件类型
 */
zxt.ui.Widget.prototype.getType = function(){
	return "zxt.ui.Widget";
};

/**
 * <p>
 * 设置控件的父控件
 * </p>
 * 
 * @function
 * @param {Widget} 父控件
 */
zxt.ui.Widget.prototype.setParent = function(parent) {
	this._parent = parent;
};

/**
 * <p>
 * 返回控件的父控件
 * </p>
 * 
 * @function
 * @return {Widget} 父控件
 */
zxt.ui.Widget.prototype.getParent = function() {
	return this._parent;
};
/**
 * <p>
 * 返回该控件支持的操作类型列表
 * </p>
 * <p>
 * 子类必须覆盖该方法, 以返回正确的值。
 * </p>
 * 
 * @function
 * @returns {string[]} 该控件支持的操作类型列表
 */
zxt.ui.Widget.prototype.getSupportOperations = function() {
	return [];
};

/**
 * <p>
 * 该控件的消息处理函数
 * </p>
 * <p>
 * 子类必须覆盖该方法, 以返回正确的值。
 * </p>
 * 
 * @function
 * @param {Message} msg 接受到的消息对象
 */
zxt.ui.Widget.prototype.onMessage = function(msg) {
};

/**
 * <p>配置控件</p>
 * 
 * @function
 * @param {Object} conf 配置对象
 */

zxt.ui.Widget.prototype.conf = function(conf) {
	
};

/**
 * <p>(string) [GETTER | SETTER] 控件显示模式</p>
 *
 * @function
 * @param {String} v 显示模式参数
 * @return {String} <p>如果参数有效，则设置控件的显示模式；如果没有传入参数，则
 *                  判断当前控件的显示模式是否有效，有效则返回该设置；否则，取父控件
 *                  的显示模式，如果不存在父控件，则返回null
 *                  </p>
 */
zxt.ui.Widget.prototype.mode = function(v) {
	if (v === undefined) {
		if ( zxt.util.isValue(this._mode) ){
			return this._mode;
		} else {
			var parent = this.getParent();
			if ( zxt.util.isValue(parent) )
				return this.getParent().mode();
			
			return null;	
		}		
	};
	this._mode = v;
};

/**
 * <p>焦点切换模式</p>
 * @param {String} v 焦点切换模式参数
 * @return {String} <p>如果参数有效，则设置控件的焦点切换模式；如果没有传入参数，则
 *                  判断当前控件的焦点切换模式是否有效，有效则返回该设置；否则，取父控件
 *                  的焦点切换模式，如果不存在父控件，则返回null
 *                  </p>
 */
zxt.ui.Widget.prototype.focusMode = function(v) {
	if (v === undefined) {
		if ( zxt.util.isValue(this._focusMode) ){
			return this._focusMode;
		} else {
			var parent = this.getParent();
			if ( zxt.util.isValue(parent) )
				return this.getParent().focusMode();
			
			return null;	
		}		
	};
	this._focusMode = v;
};

/**
 * <p>
 * 该控件把自己渲染成DOM节点的函数
 * </p>
 * <p>
 * 子类不用覆盖该方法, 子类应该覆盖renderSelf方法
 * </p>
 * 
 * @function
 * @return {DOM} 渲染成的DOM节点
 */
zxt.ui.Widget.prototype.render = function() {
	/**
	this._skeleton.empty();
	var dom = this.renderSelf();		
	this._skeleton.append(dom);	
	return this._skeleton.get(0);
	**/
	return this.renderSelf();
};

/**
 * <p>设置控件模式并渲染成DOM节点的函数</p>
 * @function
 * @return {DOM} DOM节点对象
 */
zxt.ui.Widget.prototype.renderMode = function(v){
	this.mode(v);
	this.render();
}

/**
 * <p>获得DOM节点对象</p>
 * @function
 * @return {DOM} DOM节点对象
 */
zxt.ui.Widget.prototype.getDOM = function() {
	return this._skeleton.get(0);
};

/**
 * <p>
 * 一般情况下, 控件渲染成DOM节点的函数; 该函数一般不会直接调用, render函数会根据当前控件的状态选择调用该函数; 
 * 譬如当前是隐藏状态, render函数会直接渲染成标签, 如果是正常状态, render函数会调用renderSelf函数来渲染自己.
 * </p>
 * <p>
 * 子类必须覆盖该方法, 渲染成DOM节点
 * </p>
 * 
 * @function
 * @return {DOM} 渲染成的DOM节点
 */
zxt.ui.Widget.prototype.renderSelf = function() {
	throw new Error("renderSelf NOT implemented!");
};

/**
 * <p>控件编辑模式设置</p>
 * @function
 * @param {String} v 控件编辑模式
 * @return
 */
zxt.ui.Widget.prototype.enable = function(v) {
	if(v){
		this.mode("NORMAL");
	}else{
		this.mode("DISABLE");
	};
	this.render();
};


/**
 * <p>控件焦点切换函数</p>
 * 
 * @private 不允许重写
 * @function
 */
zxt.ui.Widget.prototype.focus = function(){
	if ( this._focused == 1 ){
		return 0;
	};
	if (this.mode() == "DISABLE"||this.mode()=="LABEL"||this.mode()=="MASK"||this.mode()=="READONLY"){
		return 0;
	};
	this.focusSelf();
	this.onFocus();
	return 1;
};

zxt.ui.Widget.prototype.focusSelf = function(){	
};

/**
 * <p>
 * 控件失去焦点函数
 * </p>
 * 
 * @private
 * @function
 */
zxt.ui.Widget.prototype.blur = function(){
	this.blurSelf();
	this.onBlur();
	return 1;
};

zxt.ui.Widget.prototype.blurSelf = function(){
};


zxt.ui.Widget.prototype.onFocus = function(){
	this.whenFocus();
	this._focused = 1;
	var parent = this.getParent();
	if ( zxt.util.isValue(parent) )
		return parent._onChildFocusChange(this, this, true);
};

/**
 * <p>
 * 控件获得焦点事件，通常子控件要重写
 * </p>
 * 
 * @private
 * @function
 */
zxt.ui.Widget.prototype.whenFocus = function(){
}; 

zxt.ui.Widget.prototype.onBlur = function(){
	this.whenBlur();		
	this._focused = 0;
	var parent = this.getParent();
	if ( zxt.util.isValue(parent) )
		return parent._onChildFocusChange(this, this, false);
}; 

/**
 * <p>控件校验状态</p>
 * @param {} v
 * @param {zxt.ui.Widget} type 控件校验类型
 * @param {object} param 参数
 * @param {String} info 校验信息
 * @return
 */
zxt.ui.Widget.prototype.validateStatus = function(v,type,param,info){
	if (zxt.util.isAvailable(v)) {
		this._validateStatus.status = v;
		this._validateStatus.type = type;
		this._validateStatus.param = param;
		this._validateStatus.info = info;
	};
	return this._validateStatus;
}
 
/**
 * <p>
 * 控件失去焦点事件
 * </p>
 * 
 * @private
 * @event
 */
zxt.ui.Widget.prototype.whenBlur = function(){	
};



zxt.ui.Widget.prototype.onKeyDown = function(keyCode) {
};

/**
 *<p>
 * 复合控件是一种特殊的页面构件, 除了能把自己渲染成DOM节点外, 还是一个其他控件的容器比如grid控件。复合控件中有一个所有子控件的数组，空间中当前获得焦点的控件索引。
 *</p>
 *<p>
 * 该控件中有一个子控件数组和一个焦点顺序数组，默认焦点顺序数组就是子控件数组。当用户自行设定过焦点顺序数组，焦点顺序将按照焦点顺序数组。
 *</p>
 * 
 * @class 复合控件接口类
 * @extends zxt.ui.Widget
 */
zxt.ui.Composite = function(id){
	zxt.ui.Widget.call(this, id);
	this._children = [];
	this._focusCurrent = -1;	
	this._focusOrder = [];
	this._focusMode = "TAB";
	
	this._originalChildren = [];
};

zxt.defineClazz(zxt.ui.Composite, zxt.ui.Widget);

/**
 * <p>返回组件类型 - zxt.ui.Composite</p>
 * 
 * @function
 * @returns {zxt.ui.Composite} 组件类型
 */
zxt.ui.Composite.prototype.getType = function(){
	return "zxt.ui.Composite";
};

zxt.ui.Composite.prototype.onChildValueChange = function(child, old, now) {
	return true;	
};	

zxt.ui.Composite.prototype._onChildValueChange = function(child, old, now) {	
	var ret = this.onChildValueChange(child, old, now);
	if ( ret == false ) return;
	
	var parent = this.getParent();
	if ( zxt.util.isValue(parent) )
		return parent._onChildValueChange(child, old, now);	
};	


/**
 * <p>
 * 添加控件子控件
 * </p>
 * 
 * @private
 * @function
 * @param {zxt.ui.Widget} component 子控件
 */
zxt.ui.Composite.prototype.addChild = function(component){
	this._children.push(component);
	component.setParent(this);
};

/**
 * <p>
 * 删除子控件
 * </p>
 * 
 * @private
 * @function
 */
zxt.ui.Composite.prototype.removeTailChild = function(){
	this._children.pop();
};

/**
 * <p>
 * 添加控件子控件
 * </p> 
 * 
 * @function
 * @param {zxt.ui.Widget} component 子控件
 */
zxt.ui.Composite.prototype.addOriginalChild = function(component){
	this._originalChildren.push(component);
	component.setParent(this);
};

/**
 * <p>设置焦点切换数组</p>
 * @function
 * @param {Array} focusorder 焦点切换数组
 * @return {Array} 如果没有传入参数，则返回当前的焦点切换数组
 */
zxt.ui.Composite.prototype.focusOrder = function(focusorder){
	if(focusorder===undefined){return this._focusOrder;}
	if ( !zxt.util.isArray(focusorder) ){
		throw new Error("Focus Order MUST be an array." + focusorder);
	};
	this.clearFocusCurrent();
	this._focusOrder = focusorder;	
};

/**
 * <p>如果焦点切换数组没有设置，则返回所有的孩子DOM节点的ID；否则，返回焦点切换数组</p>
 * @function
 * @return {Array} <p>如果焦点切换数组没有设置，则返回所有的孩子DOM节点的ID；
 * 
 *                    否则，返回焦点切换数组</p>
 */
zxt.ui.Composite.prototype.order = function(){
	if(this.focusOrder().length==0){
		return this.originalChild().concat(this.children());
	}else{
		return this.originalChild().concat(this.focusOrder());
	};
};

/**
 * <p>获得指定下标索引的控件</p>
 * @function
 * @param {int} idx 下标索引
 * @return {String} 控件ID
 */
zxt.ui.Composite.prototype.getChild = function(idx){
	var _idx = idx % this.order().length;
	return this.order()[_idx];
};

/**
 * <p>
 * 子控件的[GETTER|SETTER]
 * </p>
 * 
 * @function
 * @param {zxt.ui.Widget[]} v 子控件
 * @returns {zxt.ui.Widget[]} 子控件
 */
zxt.ui.Composite.prototype.children = function(v){
	if (v === undefined) {	return this._children;	}
  this._children = v;
};

zxt.ui.Composite.prototype.originalChild = function(v){
	if (v === undefined) {	return this._originalChildren;	}
	this._originalChildren = v;
};

/**
 * <p>渲染DOM节点</p>
 * @return 
 */
zxt.ui.Composite.prototype.renderSelf = function(){
	for(var i=0;i<this._children.length;i++){
		this._children[i].render();
	};
};

/* Focus Stuff Related */
zxt.ui.Composite.prototype.onChildFocusChange = function(child, target, b) {
	if ( b == false ) return;	
	this._setFocusCurrent(child);
	
};	

zxt.ui.Composite.prototype._onChildFocusChange = function(child, target, b) {	
	this.onChildFocusChange(child, target, b);
		
	var parent = this.getParent();
	if ( zxt.util.isValue(parent) )
		parent._onChildFocusChange(this, target, b);	
};	

/**
 * <p>获取焦点控制</p>
 * @function
 * @param {String} v 字段ID
 * @return
 */
zxt.ui.Composite.prototype.focused = function(v){
	if (v === undefined){
		if(this._focusCurrent==-1)return null;	
		return this.order()[this._focusCurrent%this.order().length];
	};
	
	for(var i=0;i<this.order().length;i++){
		if(this.order()[i]==v){
			this._focusCurrent = i;	
			this.focusMode("TAB");		
			return;
		};
	};
};

/**
 * <p>指定ID控件获取焦点</p>
 * @private
 * @function
 * @param {String} child 子控件ID
 * @return
 */
zxt.ui.Composite.prototype._setFocusCurrent = function(child){
	if(this.focused() == child) return;
	
	this.clearFocusCurrent();	
	this.focused(child);	
};	

/**
 * <p>失去焦点</p>
 * @function
 * @return
 */
zxt.ui.Composite.prototype.clearFocusCurrent = function(){
	var child = this.focused();
	if ( zxt.util.notValue(child) ) {
		return;
	};	
		
	if ( child.instanceOf(zxt.ui.Composite) ){
		child.clearFocusCurrent();
	} else {
		child.blur();
	};	
	this._focusCurrent = -1;	
};

/**
 * <p>键盘按下处理事件</p>
 * @param event
 * @return
 */
zxt.ui.Composite.prototype.onKeyDown = function(event){	
	if(zxt.util.isAvailable(this.focused())){
		if(zxt.util.isFunction(this.focused().onKeyDown)){
			this.focused().onKeyDown(event);
		};
	};
};

zxt.ui.Composite.prototype._enterCurrent = function(){
	var child = this.focused();
	if (zxt.util.isValue(child) &&  child.instanceOf(zxt.ui.Composite) ){
		child._enterCurrent();
		return;
	};

	this.focusMode("TAB");
};

zxt.ui.Composite.prototype._leaveCurrent = function(){
	var child = this.focused();
	if ( zxt.util.isValue(child) &&  child.instanceOf(zxt.ui.Composite) ){
		child._leaveCurrent();
		return;
	};
	this._focusCurrent == -1;
	this.focusMode("DEFAULT");
};

/**
 * <p>
 * 控件自身焦点锁定
 * </p>
 * 
 * @private
 * @function
 */
zxt.ui.Composite.prototype.focus = function(forward){
	
	if ( this.focusMode() == "DEFAULT" ){		
		if ( this._focused == 1 ){return 0;};		
		this._focused = 1;		
		this.onFocus();
		return 1;
	};
	
	var fwd = forward;	
	if ( zxt.util.notValue(fwd) ) fwd = true;
	
	if ( this.order().length ==0 ){	return 0;	};
	
	var idx = 0;
	if (this._focusCurrent != -1) { idx = this._focusCurrent; };
	
	while(idx < this.order().length && idx >=0 ){
		var _child = this.getChild(idx);
		var _fs = _child.focus(fwd);
		if ( _fs > 0 ){	return 1; };
		idx = fwd?idx+1:idx-1;
	};
	return 0;	
};

/**
 * <p>
 * 控件失去焦点
 * </p>
 * 
 * @private
 * @function
 */
zxt.ui.Composite.prototype.blur = function(){
	this.onBlur();	
};


zxt.ui.Composite.prototype.whenFocus = function(){	
	
};

zxt.ui.Composite.prototype.whenBlur = function(){
	
};

/**
 * <p>交互控件是一种特殊的页面构件, 除了能把自己渲染成DOM节点外, 和可以和用户交互, 获取用户的输入.</p>
 * 
 * @class 交互控件接口类
 * @extends zxt.ui.Widget
 * @param {String} id 控件ID
 */
zxt.ui.Interactor = function(id) {
	zxt.ui.Widget.call(this, id);
	
	this.$Hide = "";
	
	this.__value = null;
	this._propagation = true;
};

zxt.defineClazz(zxt.ui.Interactor, zxt.ui.Widget);

/**
 * <p>返回组件类型</p> 
 * 
 * @function
 * @returns {zxt.ui.Interactor} 组件类型
 */
zxt.ui.Interactor.prototype.getType = function(){
	return "zxt.ui.Interactor";
};

 
/**
 * <p>验证传入的值是否合法</p>
 * 
 * @function
 * @param {String} value 验证的值
 * @return {boolean} 验证的结果
 */
zxt.ui.Interactor.prototype.validate = function(value) {
	return true;
};


zxt.ui.Interactor.prototype.propagation = function(v){
	if( v === undefined ) { return this._propagation; }
	this._propagation = v;
};

zxt.ui.Interactor.prototype._hides = function() {
	return this.$Hide.split(",");
}	

/**
 * [GETTER|SETTER] 控件内在的值
 * 
 * 该方法不能被子类覆盖
 * @function
 */
zxt.ui.Interactor.prototype.val = function(v) {
  if (v === undefined) {	return this.__value;	}
  
  var old = this.getSelfValue();
  
  if ( this.__value !== v ){  	
  	this.__value = v;  	
  };
   	
  if ( old !== this.getSelfValue()){
  		this._onValueChange(old, this.getSelfValue());
  };
  
};

/**
 * @private
 */
zxt.ui.Interactor.prototype._onValueChange = function(old, now) {
	var ret = this.onValueChange(old, now);
	if ( ret == false ) return;
	
	if ( this.propagation() ){//有父控件
		var parent = this.getParent();
		if ( zxt.util.isValue(parent) )
			return parent._onChildValueChange(this, old, now);
	};		
};

/**
 * <p>控件值发生变化后的事件</p>
 * 
 * @function
 * @return false 如果valueChange事件继续交给父控件处理, 否则返回false;
 */
zxt.ui.Interactor.prototype.onValueChange = function(old, now) {
	return true;
};

/**
 * <p>设置交互控件的值</p>
 * 
 * @function
 * @param 该交互控件的值
 */
zxt.ui.Interactor.prototype.setValue = function(value) {
	this.val(value);
};

/**
 * <p>设置交互控件的值并渲染该控件</p>
 * 
 * @function
 * @param 该交互控件的值
 */
zxt.ui.Interactor.prototype.renderValue = function(value) {
	this.setValue(value);
	this.render();
};

zxt.ui.Interactor.prototype.beforeGetValue = function() {
	
};

zxt.ui.Interactor.prototype.afterGetValue = function() {
	
};		

zxt.ui.Interactor.prototype.getSelfValue = function() {
	return this.val();
}	

zxt.ui.Interactor.prototype.getSelfLabel = function() {
	return this.getValue();
};

/**
 * <p>获取交互控件的值</p>
 * 
 * @function
 * @return 该交互控件的值
 */
zxt.ui.Interactor.prototype.getValue = function() {
	this.beforeGetValue();
	var v = this.getSelfValue();
	this.afterGetValue();	
	return v;
};

/**
 * <p>[LABEL]模式下的显示字符串</p>
 * 
 * @function
 * @return {String} [LABEL]模式下的显示字符串
 */
zxt.ui.Interactor.prototype.getLabel = function() {
	var lb = this.getSelfLabel();
	if ( zxt.util.notValue(lb) ){
		lb = "";
	} else {	
		for( var i=0; i<this._hides().length;i++ ){
			if ( this._hides()[i] == lb ){ lb = ""; }
		};
	};	
	return lb;	
};

/**
 * <p>[MASK]模式下的显示字符串</p>
 * 
 * @function
 * @return {String} [MASK]模式下的显示字符串
 */
zxt.ui.Interactor.prototype.getMask = function() {
	return "xxx";
};

/**
 * <p>交互控件的工厂类, getInstance方法能返回相应的交互控件实例.</p>
 * 
 * @class 交互控件的工厂类
 */
zxt.ui.InteractorFactory = function() {
};

/**
 * <p>获取相应的交互控件实例对象</p>
 * 
 * @function
 * @return 交互控件实例对象
 */
zxt.ui.InteractorFactory.prototype.getInstance = function() {
};

InteractorManager = {
	interactors : {},
	register : function(type, interMgr) {
		this.interactors[type] = interMgr;
	},
	getInteractorFactory : function(type, interMgr) {
		return this.interactors[type];
	},
	getInteractor : function(type) {
		var fac = this.interactors[type];
		return fac.getInstance();
	}
};

/**
 * <p>Element</p>
 * @class
 * @param {String} id 控件ID
 */
zxt.ui.Element = function(id) {
	zxt.ui.Interactor.call(this, id);
	this._inner=null;
};

zxt.defineClazz(zxt.ui.Element, zxt.ui.Interactor);

/**
 * <p>设置控件值</p>
 * @param v
 * @return
 */
zxt.ui.Element.prototype.setValue = function(v) {
	var val = v;
	if ( zxt.util.isNumber(v) ){
		val = v.toString();
		if ( /e/.test(val) ){
			if ( v>1 ){
				val = zxt.util.formatInteger(v);
			} else {
				val = zxt.util.formatDecimal(v);
			};			
		};
	};
		
	this.val(val);
};

/**
 * <p>根据不同的MODE渲染DOM节点</p>
 * @function
 * @return
 */
zxt.ui.Element.prototype.render = function() {	
	var dom = null;
	this._validateStatus = {status:true,type:null,param:null,info:""}; //每次render前将校验状态清空，解决mode切换时校验不过的问题
	if ( this._skeleton == null ){
		this._skeleton = $("<div class='zxt-skeleton' style='width:100%;'>");	
	}	
	
	if ( this.mode() == "LABEL" ){
		dom = $("<div class='zxt-Label'>");
		var label = this.getLabel();
		if( !zxt.util.isAvailable(label) ){		
			label = "&nbsp;";
		}
		dom.html(label);
	} else if ( this.mode() == "MASK") {
		dom = $("<div class='zxt-Label'>");
		dom.html(this.getMask());
	}	else {
		dom = this.renderSelf();		
	};	
	
	if ( dom != this._inner ){
		this._inner = dom;
		this._skeleton.empty();
		this._skeleton.append(dom);			
	};	
	return this._skeleton;
};

/**
 * <p>控件代理</p>
 * @class
 * @param {String} id 控件ID
 * 
 */
zxt.ui.WidgetProxy = function(id) {
	zxt.ui.Interactor.call(this, id);
};

zxt.defineClazz(zxt.ui.WidgetProxy, zxt.ui.Element);

/**
 * <p>渲染空的DOM节点</p>
 * @function
 * @return {DOM} 空
 */
zxt.ui.WidgetProxy.prototype.render = function() {	
	return null;
};

/**
 * <p>获得焦点</p>
 * @function
 * @return {int} 0
 */
zxt.ui.WidgetProxy.prototype.focus = function(){
	return 0;
};

/**
 * <p>失去焦点</p>
 * @function
 * @return {int} 0
 */
zxt.ui.WidgetProxy.prototype.blur = function(){
	return 0;
};


/**
 * <p>该类表示一个选择器控件, 包括select combobox Listbox Choose等。
 * 该类继承CompositeInteractor
 * 该类提供 所有选择器共有的公共接口</p>
 * @class 页面控件接口类
 * 
 */

zxt.ui.AbstractSelect = function(){
	zxt.ui.Interactor.call(this);
	
	this.$Format = null;
	this.$PadLength = null;
	
	this._options = new Array();
	this._labels = new Array();
	this._labelonly = true;
	
};

zxt.defineClazz(zxt.ui.AbstractSelect, zxt.ui.Interactor);

/**
 * 返回组件类型 - zxt.ui.AbstractSelect
 * 
 * @function
 * @returns {string} 组件类型
 */
zxt.ui.AbstractSelect.prototype.getType = function(){
	return "zxt.ui.AbstractSelect";
};

/**
 * <p>
 * 添加选项
 * </p>
 * 
 * @function
 * @param {string} value 选项的值
 * @param {string} label 选项的显示内容
 */
zxt.ui.AbstractSelect.prototype.addOption = function(value, label) {	
	var opt = {};
	opt.label =label;
	opt.value =value;	
	this.appendOption(opt);
};

/**
 * <p>添加选项</p>
 * @param {Object} opt
 * @return
 */
zxt.ui.AbstractSelect.prototype.appendOption = function(opt) {
	this.beforeOptionAdded(opt.value, opt.label);
	this._options.push(opt);
	this.afterOptionAdded(opt);
};


zxt.ui.AbstractSelect.prototype.beforeOptionAdded = function(value,label){
	return;
};

zxt.ui.AbstractSelect.prototype.afterOptionAdded = function(opt){
	return;
};

/**
 * <p>清空配置选项</p>
 * @return
 */
zxt.ui.AbstractSelect.prototype.clearOptions = function(){
	this._options.length=0;
	this._labels.length = 0;
};

/**
 * <p>设置选项</p>
 * @param {Object} v 选项参数
 * @return 如果没有上送参数，则返回当前参数设置
 */
zxt.ui.AbstractSelect.prototype.options = function(v){
	if( v === undefined ) { return this._options; }
	this._options = v;
};

/**
 * <p>配置项</p>
 * @param {Object} conf 配置
 * @return
 */
zxt.ui.AbstractSelect.prototype.conf = function(conf) {
	
	var opts = conf["_options"];
	if ( zxt.util.isValue(opts) )
		this.options(opts);
	
	this.config(conf);	
};

/**
 * <p>[LABEL]模式下的显示字符串</p>
 * 
 * @function
 * @return [LABEL]模式下的显示字符串
 */
zxt.ui.AbstractSelect.prototype.getSelfLabel = function(){	
	var val = this.val();
	var op = this.getOptionByValue(val);
	if ( zxt.util.notValue(op) ){
		return val;
	};	
	
	return this.getOptionText(op);
};

/**
 * <p>通过值寻找对应的标签</p>
 * @private
 * @function
 * @returns {boolean} 返回true
 */
zxt.ui.AbstractSelect.prototype.getOptionByValue = function(content) {
	for ( var i = 0; i < this._options.length; i++) {
		var op = this._options[i];
		if (content == op.value) {
			return op;
		}
	};
	return null;
};

/**
 * <p>通过标签寻找对应的值</p>
 * @private
 * @function
 * @param {String} content 标签内容
 * @returns {String} 标签对应的值;若没有找到，则返回null
 */
zxt.ui.AbstractSelect.prototype.getOptionByLabel = function(content) {
	for ( var i = 0; i < this._options.length; i++) {
		var op = this._options[i];
		var opL = this.getOptionText(op);		
		if (content == opL) {
			return op;
		}
	};
	return null;
};

/**
 * <p>设置标签值</p>
 * @param {String} l 标签内容
 * @return
 */
zxt.ui.AbstractSelect.prototype.setLabel = function(l){
	var opt = this.getOptionByLabel(l);
	if ( opt == null ) return;
	this.setValue(opt.value);	
};	

/**
 * <p>
 * 保存标签设置，如果当前的配置选项没有值，则返回false;否则，
 * 将标签写入到当前对象的标签数组中
 * </p>
 * @function
 * @return {boolean} 如果当前的配置选项没有值，则返回false
 */
zxt.ui.AbstractSelect.prototype._createLabels = function(){
	this._labels.length = 0;
	if ( zxt.util.notValue(this._options) ){
		return;
	};
	
	for ( var i = 0; i < this._options.length; i++) {
		var op = this._options[i];
		var displayLabel = this.getOptionText(op);
		this._labels.push(displayLabel);
	};
};

/**
 * <p>返回处理后的内容</p>
 * @param {String} v 内容参数
 * @return {String} 如果参数内容为空且不需要补零，则返回空；否则，做左补零处理
 */
zxt.ui.AbstractSelect.prototype.getValueText = function(v){
	if ( zxt.util.isEmptyString(v) || ( !zxt.util.isValue(this.$PadLength)) ){
		return v;
	};	
	
	return zxt.util.stringPadLeft(v, this.$PadLength);	
}	

/**
 * <p>获取配置项描述</p>
 * @param {Object} op 配置选项
 * @return {String} 如果配置选项的值和标签均为空，则返回空；否则，左补零后的值+标签
 */
zxt.ui.AbstractSelect.prototype.getOptionText = function(op){
	if(op.value==""&&op.label==""){return "";}
	var displayLabel = this.$Format||"$LABEL$";
	var vt = this.getValueText(op.value);	
	displayLabel = displayLabel.replace("$VALUE$", vt);
	displayLabel = displayLabel.replace("$LABEL$", op.label);	
	return displayLabel;
};

/**
 * <p>
 * 后台加载选项
 * </p>
 * 
 * @function
 * @param {zxt.data.TunnelTableModel} dm 后台传过来的值的集合
 * 
 */
zxt.ui.AbstractSelect.prototype.load = function(dm){
	var opts = dm.get(0);
	for( var i=0; i<opts.length; i++ ){
		var opt = opts[i];
		this.addOption(opt.value, opt.label);	
	}	
};

/**
 * @ignore
 */
zxt.ui.Record = function() {
	zxt.ui.Interactor.call(this);
	zxt.ui.Composite.call(this);

	this._interactors = {};
	this._interactorChanged = false;
};

zxt.defineClazz(zxt.ui.Record, zxt.ui.Interactor, zxt.ui.Composite);

zxt.ui.Record.prototype.validate = function(value) {
	return true;
};

zxt.ui.Record.prototype.getSelfValue = function() {
	var ret = {};

	for ( var f in this._interactors) {
		var fInt = this._interactors[f];
		var _input = fInt.getValue();
		ret[f] = _input;
	}
	return ret;
};

zxt.ui.Record.prototype._renderInteractors = function() {
	var host = this;
	for ( var f in this._interactors) {
		var fInt = this._interactors[f];
		var fVal = this.val()[f];
		fInt.setValue(fVal);
		fInt.render();
	};
};

zxt.ui.Record.prototype.mapInteractor = function(f, fInt) {
	this._interactors[f] = fInt;
	this._interactorChanged = true;
};

zxt.ui.Record.prototype.getInteractor = function(f) {
	return this._interactors[f];
};

zxt.ui.Record.prototype.getInteractors = function(f) {
	return this._interactors;
};

/**
 * @ignore
 */
zxt.ui.ModeInteractor = function(mode) {
	zxt.ui.Interactor.call(this);
	this._displays = {};
	this._mode = mode || zxt.type.Mode.VIEW;

	this._jqDom = $("<div>");
};

zxt.defineClazz(zxt.ui.ModeInteractor, zxt.ui.Interactor);

zxt.ui.ModeInteractor.prototype.getType = function() {
	return "zxt.ui.ModeInteractor";
};	

zxt.ui.ModeInteractor.prototype.setModeDisplay = function(mode, display) {
	this._displays[mode] = display;
};

zxt.ui.ModeInteractor.prototype.onModeChange = function(mode) {
	// var inner = this._displays[this._mode];
	// this.setValue( inner.getValue() );
	if (this._mode == mode) {
		return;
	};
	this._mode = mode;
	this._renderInner();
};

zxt.ui.ModeInteractor.prototype.getSelfValue = function() {
	var inner = this._displays[this._mode];
	return inner.getValue();
};

zxt.ui.ModeInteractor.prototype.focus = function(){
	var inner = this._displays[this._mode];
	return inner.focus();
};	

zxt.ui.ModeInteractor.prototype._renderInner = function() {
	var inner = this._displays[this._mode];
	inner.setValue(this.val());
	var innerDom = inner.render();
	this._jqDom.empty();
	this._jqDom.append(innerDom);
};

zxt.ui.ModeInteractor.prototype.render = function() {
	this._renderInner();
	return this._jqDom.get(0);
};

/**
 * @ignore
 */
zxt.ui.ModeInteractorFactory = function(mode) {
	zxt.ui.InteractorFactory.call(this);
	this._mode = mode;
	this._factories = {};
};

zxt.defineClazz(zxt.ui.ModeInteractorFactory, zxt.ui.InteractorFactory);

zxt.ui.ModeInteractorFactory.prototype.setModeFactory = function(mode, factory) {
	this._factories[mode] = factory;
};

zxt.ui.ModeInteractorFactory.prototype.getInstance = function() {
	var ret = new zxt.ui.ModeInteractor(this._mode);
	for ( var m in this._factories) {
		var fac = this._factories[m];
		ret.setModeDisplay(m, fac.getInstance());
	};
	return ret;
};

/**
 * @ignore
 */
zxt.ui.ColumnInteractor = function(col, vmode) {
	zxt.ui.Composite.call(this);
	zxt.ui.Interactor.call(this);
		
	this._column = col;
	this._vmode = vmode || zxt.type.Mode.VIEW;
	this._jqDom = null;

	this._viewIF = null;
	this._editIF = null;
	
	this._viewIT = null;
	this._editIT = null;

	this._interactor = null;
	this._conf = null;
};

zxt.defineClazz(zxt.ui.ColumnInteractor, zxt.ui.Interactor, zxt.ui.Composite);
zxt.ui.ColumnInteractor.prototype.focus = zxt.ui.Composite.prototype.focus;
zxt.ui.ColumnInteractor.prototype.blur = zxt.ui.Composite.prototype.blur;


zxt.ui.ColumnInteractor.prototype.getType = function() {
	return "zxt.ui.ColumnInteractor";
};	

zxt.ui.ColumnInteractor.prototype.getSelfValue = function() {
	if ( zxt.util.isValue(this._interactor) ){
		return this._interactor.getValue();
	};	
	return this.val();
	
};

zxt.ui.ColumnInteractor.prototype.vmode = function(v) {
	if (v == undefined) {
		return this._vmode;
	};
	this._vmode = v;
};

zxt.ui.ColumnInteractor.prototype.conf = function(conf) {
	this._conf = conf;
};	

zxt.ui.ColumnInteractor.prototype.addChild = function(component){
	this.removeTailChild();
	this._children.push(component);
	component.setParent(this);
};

zxt.ui.ColumnInteractor.prototype._renderInner = function() {
	this._viewIT = this._viewIF.getInstance();
	this._editIT = this._editIF.getInstance();
	
	this._editIT.conf(this._conf);
	this._editIT.setValue(this.val());
		
	if (this._vmode == zxt.type.Mode.CRET) {
		this._interactor = this._editIT;
		this.addChild(this._interactor);
		var innerDom = this._interactor.render();	
		this._jqDom.empty().append(innerDom);
	} else if (this._vmode == zxt.type.Mode.EDIT && (!this._column.readonly() ) ) {
		this._interactor = this._editIT;
		this.addChild(this._interactor);
		var innerDom = this._interactor.render();	
		this._jqDom.empty().append(innerDom);
	} else {
		this._viewIT.conf(this._conf);
		this._viewIT.setValue(this.val());
		this._viewIT.label(this._editIT.getLabel());
		
		this._interactor = this._viewIT;
		this.addChild(this._interactor);
		//var innerDom = this._interactor.render();	
		var innerHTML = this._interactor.html();
		this._jqDom.html(innerHTML);
	};	
};

zxt.ui.ColumnInteractor.prototype.renderSelf = function() {

	if ( this._jqDom == null ){
		this._jqDom = $("<div>");
	};	

	if (this._viewIF == null || this._editIF == null) {
		this._viewIF = InteractorManager.getInteractorFactory("label");
		this._editIF = InteractorManager.getInteractorFactory(this._column.type());
	};

	this._renderInner();
	return this._jqDom.get(0);
};


zxt.ui.ColumnInteractor.prototype.focus = function(){
	return this._interactor.focus();
};

zxt.ui.ColumnInteractor.prototype.blur = function(){
	this._interactor.blur();
};

zxt.ui.ColumnInteractor.prototype.onKeyDown = function(keyCode){
	this._interactor.onKeyDown(keyCode);
};

zxt.ui.ColumnInteractor.prototype.focusChild = function(){
	this.getParent().focusChild();
};

zxt.ui.ColumnInteractor.prototype.onMessage = function(msg) {
	var _event_type = msg.type;
	switch (_event_type) {
	case zxt.core.MESSAGETYPE.WM_MODE_CHANGE:
		var _vmode = msg.data.mode;
		if (this._vmode != _vmode) {
			this.vmode(_vmode);
			this.render();
		}
		break;
	default:
	};
};

/**
 * @ignore
 */
zxt.ui.ColumnInteractorFactory = function(col, vmode) {
	zxt.ui.InteractorFactory.call(this);
	this._column = col;
	this._vmode = vmode || zxt.type.Mode.VIEW;
};

zxt.defineClazz(zxt.ui.ColumnInteractorFactory, zxt.ui.InteractorFactory);

zxt.ui.ColumnInteractorFactory.prototype.getInstance = function() {
	var _int = new zxt.ui.ColumnInteractor(this._column, this._vmode);
	return _int;
};






